import time
import logging

from paramiko import SSHClient, AutoAddPolicy
from paramiko.channel import Channel
from paramiko.ssh_exception import AuthenticationException, NoValidConnectionsError

# logging.basicConfig(level=logging.DEBUG)


class BaseSSH:
    enter = b'\n'

    def __init__(self, *args, **kwargs):

        """"将传递过来的值动态的给对象赋予属性"""
        # for k, v in kwargs.items():
        #     setattr(self, k, v)
        """初始化连接参数"""
        self.args: tuple = args
        self.kwargs: dict = kwargs
        self._device: str = kwargs.get('device')
        self._hostname: str = kwargs.get('hostname')
        self._host: str = kwargs.get('host')
        self._username: str = kwargs.get('username')
        self._password: str = kwargs.get('password')
        self._port: int = int(kwargs.get('port', 22))
        self._status: bool = False
        self._ssh: Channel | dict = self._connect()

    def __del__(self):
        """销毁对象时关闭通道"""
        try:
            if isinstance(self._ssh, Channel):
                self._ssh.close()
        except Exception:
            pass

    def _response(self, data: str) -> dict:
        """统一返回值结构"""
        return dict(device=self._device, hostname=self._hostname, host=self._host, status=self._status, data=data)

    def _connect(self) -> Channel | dict:
        """创建连接"""
        try:
            ssh = SSHClient()
            ssh.set_missing_host_key_policy(AutoAddPolicy())
            logging.info(f"正在连接：：{self._device}")
            ssh.connect(hostname=self._host, port=self._port, username=self._username, password=self._password,
                        look_for_keys=False, auth_timeout=10)
            client = ssh.invoke_shell()
            self._screen(client)
            return client
        except AuthenticationException:
            message = self._response(data="认证失败")
            return message
        except TimeoutError:
            message = self._response(data="连接超时")
            return message
        except NoValidConnectionsError:
            message = self._response(data="ssh服务异常")
            return message
        except Exception as e:
            message = self._response(data=f"异常报错{str(e)}")
            return message

    def _screen(self, c: Channel):
        """关闭设备分屏"""
        time.sleep(0.5)
        c.send(b"screen-length disable" + self.enter)

    @property
    def get_configure(self) -> dict:
        """获取配置"""
        if not isinstance(self._ssh, Channel):
            return self._ssh
        self._ssh.send(b"display current-configuration" + self.enter)
        time.sleep(10)
        try:
            recv: str = self._ssh.recv(65535).decode()
            self._status = True
            message: dict = self._response(data=recv)
            return message
        except UnicodeDecodeError:
            message = self._response(data="解码失败")
            return message
        except Exception as e:
            message = self._response(data=f"获取异常报错{str(e)}")
            return message


def run_s(*args, **kwargs) -> dict:
    """启动程序"""
    s = BaseSSH(*args, **kwargs)
    data = s.get_configure
    return data


if __name__ == '__main__':
    pass
